import React, {PropsWithChildren, useEffect, useMemo, useState} from 'react'
import {View} from "@tarojs/components";
import styles from "./procurementReturnDetail.module.sass"
import {ExcelColumn, exportToWorkbook, saveAndOpenWorkbook} from "../utils/ExcelUtils";
import Taro, {useLoad} from "@tarojs/taro";
import employeeStore from "../store/EmployeeStore";
import MyNavigationBar, {useMyNavigationBarHeight} from "../components/MyNavigationBar";
import {Button, Cell, CellGroup, SafeArea, Space} from "@nutui/nutui-react-taro";
import {DATE_WITH_HOUR_MINUTE_FORMATER, DATE_WITH_TIME_FORMATER} from "../utils/Date";
import {Add, Top} from "@nutui/icons-react-taro";
import ExportToExcelConfigurationDialog from "../components/ExportToExcelConfigurationDialog";
import {OffsetDateTime} from "@js-joda/core";
import OrderListItem from "../components/OrderListItem";
import ArrayUtils from "@zxy-cn/array-utils";
import ScanBarcodeButton from "../components/ScanBarcodeButton";
import {barcodeRepeated, scanSuccess} from "../utils/ScanCodeUtils";
import SelectGoodsPopup from "../components/SelectGoodsPopup";
import procurementReturnPageStackStore from "../store/ProcurementReturnPageStackStore";
import {
    addProcurementReturnItemFromBarcode, addProcurementReturnItemsFromSubGoodsKeyList,
    deleteProcurementReturnItem,
    deleteProcurementReturnItemSub,
    getProcurementReturnDetail,
    ProcurementReturnItem,
    submitProcurementReturn,
    updateProcurementReturnItemAmount,
    updateProcurementReturnItemNote, updateProcurementReturnItemPrice,
    updateProcurementReturnItemSubAmount, updateProcurementReturnItemSubNote, updateProcurementReturnItemSubPrice
} from "../apis/ProcurementReturnApi";
import {observer} from "mobx-react";

export interface ProcurementReturnDetailProps extends PropsWithChildren {

}

const PROCUREMENT_RETURN_ITEMS_EXPORT_COLUMNS_KEY = "PROCUREMENT_ITEMS_EXPORT_COLUMNS"

const columns: ExcelColumn<ProcurementReturnItem>[] = [
    {
        key: "barcode",
        header: "条码",
    }, {
        key: "subGoodsNumber",
        header: "子商品编码",
        renderToString: item => item.subGoods?.number ?? ""
    }, {
        key: "subGoodsName",
        header: "子商品名称",
        renderToString: item => item.subGoods?.name ?? ""
    },
    {
        key: "name",
        header: "名称",
    }, {
        key: "amountInOrder",
        header: "数量",
        renderToString: item => {
            // basic unit
            return `${item.amountInOrder}`
        }
    },
    {
        key: "price",
        header: "零售价",
    },
    {
        key: "purchasePrice",
        header: "采购价",
    },
    {
        key: "note",
        header: "备注",
    },
    {
        key: "boxSpecification",
        header: "箱规",
    },
];


const ProcurementReturnDetail: React.FC<ProcurementReturnDetailProps> = ({}) => {
    const [title, setTitle] = useState("采购详情")
    const [procurementReturnId, setProcurementReturnId] = useState<number>()
    const data = procurementReturnPageStackStore.detail
    useLoad((params) => {
        setProcurementReturnId(params.id)
    })
    useEffect(() => {
        if (procurementReturnId) {
            Taro.showLoading()
            getProcurementReturnDetail(procurementReturnId)
                .then(response => {
                    procurementReturnPageStackStore.setDetail(response.data)
                    setTitle(response.data.supplier.name + "退货单明细")
                }).finally(() => {
                Taro.hideLoading()
            });
        }
    }, [procurementReturnId]);

    const canDelete = useMemo(() => {
        return employeeStore.hasAuthority("采购_退货_修改") && data && !data.submittedDateTime
    }, [employeeStore.employee, data]);

    const canSubmit = useMemo(() => {
        return employeeStore.hasAuthority("采购_退货_创建") && !!data && !data.submittedDateTime
    }, [employeeStore.employee, data]);


    const canEdit = useMemo(() => {
        return employeeStore.hasAuthority("采购_退货_修改") && (canSubmit)
    }, [canSubmit, employeeStore.employee]);

    const [selectGoodsPopupVisible, setSelectGoodsPopupVisible] = useState(false)

    const [exportToExcelDialogVisible, setExportToExcelDialogVisible] = useState(false)

    function scrollToBottom() {
        Taro.pageScrollTo({
            scrollTop: 999999,
        })
    }

    let myNavigationBarHeight = useMyNavigationBarHeight();
    // const [deleting, setDeleting] = useState(false)
    return <>
        <MyNavigationBar>{title}</MyNavigationBar>
        {data && <>
            <CellGroup divider={false} style={{position: "sticky", top: myNavigationBarHeight + 'px', zIndex: 999}}>
                <Cell>{data.createdBy.name}创建于{data.createdDateTime.format(DATE_WITH_HOUR_MINUTE_FORMATER)}</Cell>
                {data.submittedDateTime && <Cell title={"提交时间"}
                                                 extra={(data.submittedDateTime).format(DATE_WITH_HOUR_MINUTE_FORMATER)}></Cell>}
                {(canDelete || canSubmit) &&
                    <Cell extra={
                        <Space>
                            <Button onClick={async () => {
                                setExportToExcelDialogVisible(true)
                            }}>导出</Button>
                            <ExportToExcelConfigurationDialog
                                visible={exportToExcelDialogVisible}
                                rememberedColumnsStorageKey={PROCUREMENT_RETURN_ITEMS_EXPORT_COLUMNS_KEY}
                                selectableColumns={columns}
                                onCancel={() => {
                                    setExportToExcelDialogVisible(false)
                                }}
                                onConfirm={async values => {
                                    let workbook = exportToWorkbook(data.items, columns.filter(it => values.includes(it.key)));
                                    await saveAndOpenWorkbook(workbook, `${data?.supplier.name}${(data.createdDateTime).format(DATE_WITH_TIME_FORMATER)}`)
                                    setExportToExcelDialogVisible(false)
                                }}/>
                            {/*{canDelete &&*/}
                            {/*    <Button type={"danger"} fill={"outline"} loading={deleting} onClick={async () => {*/}
                            {/*        setDeleting(true)*/}
                            {/*        try {*/}
                            {/*            await deleteProcurementReturn(data.id)*/}
                            {/*            procurementPageStackStore.removeItemByKey(data.id)*/}
                            {/*            await Taro.navigateBack()*/}
                            {/*        } finally {*/}
                            {/*            setDeleting(false)*/}
                            {/*        }*/}
                            {/*    }}>删除</Button>}*/}
                            {canSubmit && <Button type={"primary"}
                                                  onClick={() => {
                                                      Taro.showModal({
                                                          title: "确定要提交吗",
                                                          content: "提交后你可能无法再修改"
                                                      }).then(result => {
                                                          if (result.confirm)
                                                              submitProcurementReturn(procurementReturnId!!).then(() => {
                                                                  procurementReturnPageStackStore.updateDetail({
                                                                      ...data,
                                                                      submittedDateTime: OffsetDateTime.now(),
                                                                  })
                                                              })
                                                      })
                                                  }}>提交</Button>}

                        </Space>
                    }/>}
            </CellGroup>
            {data.items.map((item, index) => {
                return <OrderListItem data={{...item, units: [], unit: undefined,price:item.returnPrice,}}
                                      onUpdatePrice={async price => {
                                          if (!item.subGoods){
                                              await updateProcurementReturnItemPrice(procurementReturnId!!,item.id,price)
                                          }else {
                                              await updateProcurementReturnItemSubPrice(procurementReturnId!!,item.id,price,item.subGoods.id)
                                          }
                                          Taro.showToast({
                                              title: "修改退货价成功！",
                                              icon: "success",
                                          })
                                          let items = Array.from(data!.items);
                                          items[index] = {
                                              ...items[index],
                                              returnPrice:price,
                                          }
                                          procurementReturnPageStackStore.updateDetail({
                                              ...data,
                                              items: items
                                          })
                                      }}
                                      canEdit={canEdit}
                                      onClick={() => {
                                          Taro.navigateTo({url: `/pages/goodsDetail?id=${item.id}`})
                                      }}
                                      onDelete={async () => {
                                          if (!item.subGoods) {
                                              await deleteProcurementReturnItem(procurementReturnId!!, item.id)
                                          } else {
                                              await deleteProcurementReturnItemSub(procurementReturnId!!, item.id, item.subGoods.id)
                                          }
                                          ArrayUtils.remove(data!.items, item)
                                          procurementReturnPageStackStore.updateDetail({
                                              ...data,
                                              items: Array.from(data?.items),
                                          })
                                      }}
                                      onUpdateAmount={async (value, _) => {
                                          if (!item.subGoods) {
                                              await updateProcurementReturnItemAmount(procurementReturnId!!, item.id, {
                                                  amount: value
                                              });
                                          } else {
                                              await updateProcurementReturnItemSubAmount(procurementReturnId!!, item.id, {
                                                  amount: value
                                              }, item.subGoods.id);
                                          }
                                          Taro.showToast({
                                              title: "修改数量成功！",
                                              icon: "success",
                                          })
                                          let items = Array.from(data!.items);
                                          items[index] = {
                                              ...items[index],
                                              amountInOrder: value,
                                          }
                                          procurementReturnPageStackStore.updateDetail({
                                              ...data,
                                              items: items
                                          })
                                      }}
                                      onUpdateNote={async (note) => {
                                          if (!item.subGoods) {
                                              await updateProcurementReturnItemNote(procurementReturnId!!, item.id, note)
                                          } else {
                                              await updateProcurementReturnItemSubNote(procurementReturnId!!, item.id, note, item.subGoods.id)
                                          }
                                          let items = Array.from(data!.items);
                                          items[index].note = note
                                          procurementReturnPageStackStore.updateDetail({
                                              ...data,
                                              items: items
                                          })
                                      }}
                />
            })}
            {!!data && <View className={styles.bottomPlaceholder}>
                <SafeArea position={"bottom"}/>
            </View>}
            {!!data && <View className={styles.bottomBar}>
                <Space className={styles.bottomSpace}>
                    <Button fill={"outline"} icon={<Top/>} onClick={() => {
                        Taro.pageScrollTo({
                            scrollTop: 0,
                            duration: 300,
                        })
                    }}>回到顶部</Button>
                    {canEdit && <Button icon={<Add/>} type={"primary"} onClick={() => {
                        setSelectGoodsPopupVisible(true)
                    }}>添加{`(${data.items.length})`}</Button>}
                    {canEdit && <ScanBarcodeButton onScanSuccess={async (barcode, continueScan) => {
                        if (data.items.map(it => it.barcode).includes(barcode)) {
                            await barcodeRepeated(`订单中已存在此货品\t${barcode}`)

                            setTimeout(() => {
                                continueScan()
                            }, 100)
                            return
                        }
                        let response = await addProcurementReturnItemFromBarcode(procurementReturnId!!, barcode);
                        let item = response.data
                        let array = Array.from(data.items)
                        array.push({
                            ...item,
                            id: item.goodsId,
                            returnPrice: item.price,
                            amount: item.amountInOrder,
                            subGoodsList: [],
                            createdDateTime: OffsetDateTime.now(),
                            lastModifiedDateTime: OffsetDateTime.now(),
                            units: []
                        })
                        procurementReturnPageStackStore.updateDetail({...data, items: array})
                        await scanSuccess()
                        scrollToBottom()
                        // setTimeout(() => {
                        //     continueScan()
                        // }, 100)
                    }}>扫码</ScanBarcodeButton>}
                </Space>
                <SafeArea position={"bottom"}/>
            </View>}
        </>}
        <SelectGoodsPopup visible={selectGoodsPopupVisible} onClose={() => setSelectGoodsPopupVisible(false)}
                          existedGoodsList={data?.items}
                          editProcurementId={procurementReturnId}
                          onConfirm={async value => {
                              const response = (await addProcurementReturnItemsFromSubGoodsKeyList(procurementReturnId!, value))
                              let array = Array.from(data?.items ?? [])
                              procurementReturnPageStackStore.updateDetail({
                                  ...data!,
                                  items: array.concat(response.data.map(item => ({
                                      ...item,
                                      id: item.goodsId,
                                      subGoods: item.subGoods,
                                      returnPrice: item.price,
                                      amount: item.amountInOrder,
                                      subGoodsList: [],
                                      createdDateTime: OffsetDateTime.now(),
                                      lastModifiedDateTime: OffsetDateTime.now(),
                                      units: []
                                  })))
                              })
                              setTimeout(() => {
                                  scrollToBottom()
                              }, 300)
                          }}/>
    </>
}

export default observer(ProcurementReturnDetail)


